package com.unknowpupil.design.sigleton;

/**
 * Created at 2020/12/10 by w10g <br>
 * Initialize 常用的单例 ... <br>
 *
 * @author unknowpupil
 * @since 0.0.1
 */
public class 常用的单例 {


}

/**
 * 饿汉式
 * 类加载到内存，就实例化一个单例 jvm 保证线程安全
 * 推荐使用 简单
 *  缺点：不管用不用，类装载就完成实例化
 */
class Instance{
    // 不管用不用，类装载就完成实例化
    final static Instance INSTANCE = new Instance();
    private Instance(){};
    public static Instance getInstance(){
        return INSTANCE;
    }
    public void m(){
        System.out.println("m");
    }

    public static void main(String[] args) {
        Instance instance1 = Instance.getInstance();
        Instance instance2 = Instance.getInstance();
        System.out.println(instance1==instance2);
    }
}

/**
 * 双重锁
 */
class DoubleInstance{
    private   static volatile DoubleInstance INSTANCE; // 指令重排问题。
    private DoubleInstance(){
    }
    public static DoubleInstance getInstance(){
        if(INSTANCE==null){
            synchronized (DoubleInstance.class){
                if(INSTANCE==null){
                    try {
                        Thread.sleep(1);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    INSTANCE = new DoubleInstance();
                }
            }
        }
        return INSTANCE;
    }

}

/**
 * 完美之一       懒加载，保证一个实例
 * 静态内部类
 * JVM 保证单例
 * 加载外部类时候不会加载内部类，这样就可以实现单例
 */
 class StatusInstance{
    private StatusInstance(){
    }

    // 外面的类被加载的时候里面的静态内部类是不会被加载的 在调用getInstance 的时候才会被加载
    private static class StatusInstanceHolder{
        private final static StatusInstance INSTANCE = new StatusInstance();
    }
    public static StatusInstance getInstance(){
        return StatusInstanceHolder.INSTANCE;
    }
    public void m(){
        System.out.println("m");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(StatusInstance.getInstance().hashCode());
            }).start();
        }
    }

    //枚举类单例
    enum Insta{
        INSTANCE;
    }
}